www.gusucode.com > VC++ Flash(SWF)文件创建生成Lib库源码+demo-源码程序 > VC++ Flash(SWF)文件创建生成Lib库源码+demo-源码程序/code/SWFLIB_Library/SWFMorphShape.cpp
// SWFMorphShape.cpp: implementation of the CSWFMorphShape class. // ////////////////////////////////////////////////////////////////////// #include "SWFMorphShape.h" CSWFMorphShape::CSWFMorphShape(USHORT nMorphID, USHORT depth, RECT_F startRect, RECT_F endRect) { // Init members m_ObjectType = SWF_OBJECT_TYPE_MORPH_SHAPE; m_ID = nMorphID; m_Depth = depth; m_SWFStream = NULL; m_SWFStreamLength = 0; // Init shape properties m_MorphShape.Header.TagCodeAndLength = (46 << 6) | 0x003F; m_MorphShape.Header.Length = 0; m_MorphShape.CharacterID = nMorphID; memcpy(&m_MorphShape.StartBounds, &startRect, sizeof(RECT_F)); memcpy(&m_MorphShape.EndBounds, &endRect, sizeof(RECT_F)); m_MorphShape.Offset = 0; m_MorphShape.MorphFillStyles.FillStyleCount = 0xFF; m_MorphShape.MorphFillStyles.FillStyleCountExtended = 0; m_MorphShape.MorphFillStyles.FillStyles = NULL; m_MorphShape.MorphLineStyles.LineStyleCount = 0xFF; m_MorphShape.MorphLineStyles.LineStyleCountExtended = 0; m_MorphShape.MorphLineStyles.LineStyles = NULL; m_MorphShape.StartEdges.NumberOfFillAndLineIndexBits = 0; m_MorphShape.StartEdges.ShapeRecords = NULL; m_MorphShape.EndEdges.NumberOfFillAndLineIndexBits = 0; m_MorphShape.EndEdges.ShapeRecords = NULL; memset(&m_TransformationMatrix, 0, sizeof(MATRIX_F)); // Init shape counter m_NumberStartShapes = m_NumberEndShapes = 0; } CSWFMorphShape::~CSWFMorphShape() { // Free LineStyleArray if (m_MorphShape.MorphLineStyles.LineStyles != NULL) { free(m_MorphShape.MorphLineStyles.LineStyles); m_MorphShape.MorphLineStyles.LineStyles = NULL; } // Free FillStyleArray if (m_MorphShape.MorphFillStyles.FillStyles != NULL) { // Free GradientRecordsArray for (int i=0; i<m_MorphShape.MorphFillStyles.FillStyleCountExtended; i++) { if ((m_MorphShape.MorphFillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_LINEARGRADIENT) || (m_MorphShape.MorphFillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_RADIALGRADIENT)) { delete m_MorphShape.MorphFillStyles.FillStyles[i].Gradient.GradientRecords; m_MorphShape.MorphFillStyles.FillStyles[i].Gradient.GradientRecords = NULL; } } free(m_MorphShape.MorphFillStyles.FillStyles); m_MorphShape.MorphFillStyles.FillStyles = NULL; } // Free ShapeRecordsArray if (m_MorphShape.StartEdges.ShapeRecords != NULL) { free(m_MorphShape.StartEdges.ShapeRecords); m_MorphShape.StartEdges.ShapeRecords = NULL; } if (m_MorphShape.EndEdges.ShapeRecords != NULL) { free(m_MorphShape.EndEdges.ShapeRecords); m_MorphShape.EndEdges.ShapeRecords = NULL; } if (m_SWFStream != NULL) { delete m_SWFStream; m_SWFStream = NULL; } } void CSWFMorphShape::AddLineStyle(int startWidth, SWF_RGBA startColor, int endWidth, SWF_RGBA endColor) { // Define new LineStyle entry SWF_MORPHLINESTYLE lineStyleEntry; memset(&lineStyleEntry, 0, sizeof(SWF_MORPHLINESTYLE)); lineStyleEntry.StartWidth = (USHORT)(startWidth*20); lineStyleEntry.EndWidth = (USHORT)(endWidth*20); memcpy(&lineStyleEntry.StartColor, &startColor, sizeof(SWF_RGBA)); memcpy(&lineStyleEntry.EndColor, &endColor, sizeof(SWF_RGBA)); // Add new LineStyle entry to the LineStyleArray m_MorphShape.MorphLineStyles.LineStyleCountExtended++; if (m_MorphShape.MorphLineStyles.LineStyles == NULL) m_MorphShape.MorphLineStyles.LineStyles = (SWF_MORPHLINESTYLE*)malloc(sizeof(SWF_MORPHLINESTYLE)); else m_MorphShape.MorphLineStyles.LineStyles = (SWF_MORPHLINESTYLE*)realloc(m_MorphShape.MorphLineStyles.LineStyles, m_MorphShape.MorphLineStyles.LineStyleCountExtended*sizeof(SWF_MORPHLINESTYLE)); memcpy(&m_MorphShape.MorphLineStyles.LineStyles[m_MorphShape.MorphLineStyles.LineStyleCountExtended-1], &lineStyleEntry, sizeof(SWF_MORPHLINESTYLE)); } void CSWFMorphShape::AddSolidFillStyle(SWF_RGBA startColor, SWF_RGBA endColor) { // Define new FillStyle entry SWF_MORPHFILLSTYLE fillStyleEntry; memset(&fillStyleEntry, 0, sizeof(SWF_MORPHFILLSTYLE)); fillStyleEntry.FillStyleType = SWF_FILLSTYLETYPE_SOLID; memcpy(&fillStyleEntry.StartColor, &startColor, sizeof(SWF_RGBA)); memcpy(&fillStyleEntry.EndColor, &endColor, sizeof(SWF_RGBA)); // Add new FillStyle entry to the FillStyleArray m_MorphShape.MorphFillStyles.FillStyleCountExtended++; if (m_MorphShape.MorphFillStyles.FillStyles == NULL) m_MorphShape.MorphFillStyles.FillStyles = (SWF_MORPHFILLSTYLE*)malloc(sizeof(SWF_MORPHFILLSTYLE)); else m_MorphShape.MorphFillStyles.FillStyles = (SWF_MORPHFILLSTYLE*)realloc(m_MorphShape.MorphFillStyles.FillStyles, m_MorphShape.MorphFillStyles.FillStyleCountExtended*sizeof(SWF_MORPHFILLSTYLE)); memcpy(&m_MorphShape.MorphFillStyles.FillStyles[m_MorphShape.MorphFillStyles.FillStyleCountExtended-1], &fillStyleEntry, sizeof(SWF_MORPHFILLSTYLE)); } void CSWFMorphShape::AddGradientFillStyle(UCHAR gradientFillType, RECT_F startGradientRect, RECT_F endGradientRect, SWF_MORPHGRADIENTRECORD* gradientRecords, int numRecords) { if ((numRecords > 0) && ((gradientFillType == SWF_FILLSTYLETYPE_LINEARGRADIENT) || (gradientFillType == SWF_FILLSTYLETYPE_RADIALGRADIENT))) { // Define start gradient matrix MATRIX_F startGradientMatrix; memset(&startGradientMatrix, 0, sizeof(MATRIX_F)); startGradientMatrix.scaleX = ((startGradientRect.right-startGradientRect.left)*20) / 32768; startGradientMatrix.scaleY = ((startGradientRect.bottom-startGradientRect.top)*20) / 32768; startGradientMatrix.translateX = (startGradientRect.left+startGradientRect.right) / 2; startGradientMatrix.translateY = (startGradientRect.top+startGradientRect.bottom) / 2; // Define end gradient matrix MATRIX_F endGradientMatrix; memset(&endGradientMatrix, 0, sizeof(MATRIX_F)); endGradientMatrix.scaleX = ((endGradientRect.right-endGradientRect.left)*20) / 32768; endGradientMatrix.scaleY = ((endGradientRect.bottom-endGradientRect.top)*20) / 32768; endGradientMatrix.translateX = (endGradientRect.left+endGradientRect.right) / 2; endGradientMatrix.translateY = (endGradientRect.top+endGradientRect.bottom) / 2; // Define new FillStyle entry SWF_MORPHFILLSTYLE fillStyleEntry; memset(&fillStyleEntry, 0, sizeof(SWF_MORPHFILLSTYLE)); fillStyleEntry.FillStyleType = gradientFillType; fillStyleEntry.StartGradientMatrix = startGradientMatrix; fillStyleEntry.EndGradientMatrix = endGradientMatrix; fillStyleEntry.Gradient.NumGradients = numRecords; fillStyleEntry.Gradient.GradientRecords = new SWF_MORPHGRADIENTRECORD[numRecords]; memcpy(fillStyleEntry.Gradient.GradientRecords, gradientRecords, numRecords*sizeof(SWF_MORPHGRADIENTRECORD)); // Add new FillStyle entry to the FillStyleArray m_MorphShape.MorphFillStyles.FillStyleCountExtended++; if (m_MorphShape.MorphFillStyles.FillStyles == NULL) m_MorphShape.MorphFillStyles.FillStyles = (SWF_MORPHFILLSTYLE*)malloc(sizeof(SWF_MORPHFILLSTYLE)); else m_MorphShape.MorphFillStyles.FillStyles = (SWF_MORPHFILLSTYLE*)realloc(m_MorphShape.MorphFillStyles.FillStyles, m_MorphShape.MorphFillStyles.FillStyleCountExtended*sizeof(SWF_MORPHFILLSTYLE)); memcpy(&m_MorphShape.MorphFillStyles.FillStyles[m_MorphShape.MorphFillStyles.FillStyleCountExtended-1], &fillStyleEntry, sizeof(SWF_MORPHFILLSTYLE)); } } void CSWFMorphShape::AddBitmapFillStyle(USHORT bitmapID, UCHAR bitmapFillType, RECT_F bitmapRect, RECT_F startClipRect, RECT_F endClipRect) { if ((bitmapFillType == SWF_FILLSTYLETYPE_BITMAP_0) || (bitmapFillType == SWF_FILLSTYLETYPE_BITMAP_1) || (bitmapFillType == SWF_FILLSTYLETYPE_BITMAP_2) || (bitmapFillType == SWF_FILLSTYLETYPE_BITMAP_3)) { // Define start bitmap matrix MATRIX_F startBitmapMatrix; memset(&startBitmapMatrix, 0, sizeof(MATRIX_F)); startBitmapMatrix.scaleX = ((startClipRect.right-startClipRect.left)/(bitmapRect.right-bitmapRect.left)) * 20; startBitmapMatrix.scaleY = ((startClipRect.bottom-startClipRect.top)/(bitmapRect.bottom-bitmapRect.top)) * 20; startBitmapMatrix.translateX = startClipRect.left; startBitmapMatrix.translateY = startClipRect.top; // Define end bitmap matrix MATRIX_F endBitmapMatrix; memset(&endBitmapMatrix, 0, sizeof(MATRIX_F)); endBitmapMatrix.scaleX = ((endClipRect.right-endClipRect.left)/(bitmapRect.right-bitmapRect.left)) * 20; endBitmapMatrix.scaleY = ((endClipRect.bottom-endClipRect.top)/(bitmapRect.bottom-bitmapRect.top)) * 20; endBitmapMatrix.translateX = endClipRect.left; endBitmapMatrix.translateY = endClipRect.top; // Define new FillStyle entry SWF_MORPHFILLSTYLE fillStyleEntry; memset(&fillStyleEntry, 0, sizeof(SWF_MORPHFILLSTYLE)); fillStyleEntry.FillStyleType = bitmapFillType; fillStyleEntry.BitmapID = bitmapID; fillStyleEntry.StartBitmapMatrix = startBitmapMatrix; fillStyleEntry.EndBitmapMatrix = endBitmapMatrix; // Add new FillStyle entry to the FillStyleArray m_MorphShape.MorphFillStyles.FillStyleCountExtended++; if (m_MorphShape.MorphFillStyles.FillStyles == NULL) m_MorphShape.MorphFillStyles.FillStyles = (SWF_MORPHFILLSTYLE*)malloc(sizeof(SWF_MORPHFILLSTYLE)); else m_MorphShape.MorphFillStyles.FillStyles = (SWF_MORPHFILLSTYLE*)realloc(m_MorphShape.MorphFillStyles.FillStyles, m_MorphShape.MorphFillStyles.FillStyleCountExtended*sizeof(SWF_MORPHFILLSTYLE)); memcpy(&m_MorphShape.MorphFillStyles.FillStyles[m_MorphShape.MorphFillStyles.FillStyleCountExtended-1], &fillStyleEntry, sizeof(SWF_MORPHFILLSTYLE)); } } void CSWFMorphShape::ChangeStyle(int lineStyleIndex, int fillStyleIndex0, int fillStyleIndex1, POINT_F* newPosition, bool bStart) { // Define new StyleChange entry SWF_SHAPERECORD styleChangeEntry; memset(&styleChangeEntry, 0, sizeof(SWF_SHAPERECORD)); // StateLineStyle bit styleChangeEntry.SWF_STYLECHANGERECORD.ShapeFlags |= 0x08; styleChangeEntry.SWF_STYLECHANGERECORD.LineStyle = (SHORT)lineStyleIndex; // StateFillStyle1 bit styleChangeEntry.SWF_STYLECHANGERECORD.ShapeFlags |= 0x04; styleChangeEntry.SWF_STYLECHANGERECORD.FillStyle1 = (SHORT)fillStyleIndex1; // StateFillStyle0 bit styleChangeEntry.SWF_STYLECHANGERECORD.ShapeFlags |= 0x02; styleChangeEntry.SWF_STYLECHANGERECORD.FillStyle0 = (SHORT)fillStyleIndex0; // StateMoveTo bit if (newPosition != NULL) { styleChangeEntry.SWF_STYLECHANGERECORD.ShapeFlags |= 0x01; styleChangeEntry.SWF_STYLECHANGERECORD.MoveDeltaX = (LONG)(newPosition->x * 20); styleChangeEntry.SWF_STYLECHANGERECORD.MoveDeltaY = (LONG)(newPosition->y * 20); // Calculate MoveBits int maxValue = max(abs(styleChangeEntry.SWF_STYLECHANGERECORD.MoveDeltaX), abs(styleChangeEntry.SWF_STYLECHANGERECORD.MoveDeltaY)); BYTE numMoveBits = 0; while (pow(2,numMoveBits) < maxValue) numMoveBits++; numMoveBits++; styleChangeEntry.SWF_STYLECHANGERECORD.MoveBits = numMoveBits; } // Add new StyleChange to the ShapeRecordsArray if (bStart) { m_NumberStartShapes++; if (m_MorphShape.StartEdges.ShapeRecords == NULL) m_MorphShape.StartEdges.ShapeRecords = (SWF_SHAPERECORD*)malloc(sizeof(SWF_SHAPERECORD)); else m_MorphShape.StartEdges.ShapeRecords = (SWF_SHAPERECORD*)realloc(m_MorphShape.StartEdges.ShapeRecords, m_NumberStartShapes*sizeof(SWF_SHAPERECORD)); memcpy(&m_MorphShape.StartEdges.ShapeRecords[m_NumberStartShapes-1], &styleChangeEntry, sizeof(SWF_SHAPERECORD)); } else { m_NumberEndShapes++; if (m_MorphShape.EndEdges.ShapeRecords == NULL) m_MorphShape.EndEdges.ShapeRecords = (SWF_SHAPERECORD*)malloc(sizeof(SWF_SHAPERECORD)); else m_MorphShape.EndEdges.ShapeRecords = (SWF_SHAPERECORD*)realloc(m_MorphShape.EndEdges.ShapeRecords, m_NumberEndShapes*sizeof(SWF_SHAPERECORD)); memcpy(&m_MorphShape.EndEdges.ShapeRecords[m_NumberEndShapes-1], &styleChangeEntry, sizeof(SWF_SHAPERECORD)); } } void CSWFMorphShape::AddLineSegment(POINT_F offsetPoint, bool bStart) { // Define new StraightEdge entry SWF_SHAPERECORD straightEdgeEntry; memset(&straightEdgeEntry, 0, sizeof(SWF_SHAPERECORD)); straightEdgeEntry.SWF_STRAIGHTEDGERECORD.ShapeFlags = 0x30; straightEdgeEntry.SWF_STRAIGHTEDGERECORD.DeltaX = (int)(offsetPoint.x * 20); straightEdgeEntry.SWF_STRAIGHTEDGERECORD.DeltaY = (int)(offsetPoint.y * 20); // Calculate NumBits int maxValue = max(abs(straightEdgeEntry.SWF_STRAIGHTEDGERECORD.DeltaX), abs(straightEdgeEntry.SWF_STRAIGHTEDGERECORD.DeltaY)); BYTE numBits = 0; while (pow(2,numBits) < maxValue) numBits++; numBits++; straightEdgeEntry.SWF_STRAIGHTEDGERECORD.NumBits = numBits; straightEdgeEntry.SWF_STRAIGHTEDGERECORD.ShapeFlags |= ((straightEdgeEntry.SWF_STRAIGHTEDGERECORD.NumBits-2) & 0x0F); straightEdgeEntry.SWF_STRAIGHTEDGERECORD.ShapeFlags = (straightEdgeEntry.SWF_STRAIGHTEDGERECORD.ShapeFlags << 1) | 0x01; // Add new StraightEdge to the ShapeRecordsArray if (bStart) { m_NumberStartShapes++; if (m_MorphShape.StartEdges.ShapeRecords == NULL) m_MorphShape.StartEdges.ShapeRecords = (SWF_SHAPERECORD*)malloc(sizeof(SWF_SHAPERECORD)); else m_MorphShape.StartEdges.ShapeRecords = (SWF_SHAPERECORD*)realloc(m_MorphShape.StartEdges.ShapeRecords, m_NumberStartShapes*sizeof(SWF_SHAPERECORD)); memcpy(&m_MorphShape.StartEdges.ShapeRecords[m_NumberStartShapes-1], &straightEdgeEntry, sizeof(SWF_SHAPERECORD)); } else { m_NumberEndShapes++; if (m_MorphShape.EndEdges.ShapeRecords == NULL) m_MorphShape.EndEdges.ShapeRecords = (SWF_SHAPERECORD*)malloc(sizeof(SWF_SHAPERECORD)); else m_MorphShape.EndEdges.ShapeRecords = (SWF_SHAPERECORD*)realloc(m_MorphShape.EndEdges.ShapeRecords, m_NumberEndShapes*sizeof(SWF_SHAPERECORD)); memcpy(&m_MorphShape.EndEdges.ShapeRecords[m_NumberEndShapes-1], &straightEdgeEntry, sizeof(SWF_SHAPERECORD)); } } void CSWFMorphShape::AddLineSegment(float xOffset, float yOffset, bool bStart) { // Add new StraightEdge to the ShapeRecordsArray POINT_F newPosition = {xOffset, yOffset}; AddLineSegment(newPosition, bStart); } void CSWFMorphShape::AddCurveSegment(POINT_F controlPoint, POINT_F anchorPoint, bool bStart) { // Define new CurvedEdge entry SWF_SHAPERECORD curvedEdgeEntry; memset(&curvedEdgeEntry, 0, sizeof(SWF_SHAPERECORD)); curvedEdgeEntry.SWF_CURVEDEDGERECORD.ShapeFlags = 0x20; curvedEdgeEntry.SWF_CURVEDEDGERECORD.ControlDeltaX = (int)(controlPoint.x * 20); curvedEdgeEntry.SWF_CURVEDEDGERECORD.ControlDeltaY = (int)(controlPoint.y * 20); curvedEdgeEntry.SWF_CURVEDEDGERECORD.AnchorDeltaX = (int)(anchorPoint.x * 20); curvedEdgeEntry.SWF_CURVEDEDGERECORD.AnchorDeltaY = (int)(anchorPoint.y * 20); // Calculate NumBits int maxControlValue = max(abs(curvedEdgeEntry.SWF_CURVEDEDGERECORD.ControlDeltaX), abs(curvedEdgeEntry.SWF_CURVEDEDGERECORD.ControlDeltaY)); int maxDeltaValue = max(abs(curvedEdgeEntry.SWF_CURVEDEDGERECORD.AnchorDeltaX), abs(curvedEdgeEntry.SWF_CURVEDEDGERECORD.AnchorDeltaY)); int maxValue = max(maxControlValue, maxDeltaValue); BYTE numBits = 0; while (pow(2,numBits) < maxValue) numBits++; numBits++; curvedEdgeEntry.SWF_CURVEDEDGERECORD.NumBits = numBits; curvedEdgeEntry.SWF_CURVEDEDGERECORD.ShapeFlags |= ((curvedEdgeEntry.SWF_CURVEDEDGERECORD.NumBits-2) & 0x0F); // Add new CurvedEdge to the ShapeRecordsArray if (bStart) { m_NumberStartShapes++; if (m_MorphShape.StartEdges.ShapeRecords == NULL) m_MorphShape.StartEdges.ShapeRecords = (SWF_SHAPERECORD*)malloc(sizeof(SWF_SHAPERECORD)); else m_MorphShape.StartEdges.ShapeRecords = (SWF_SHAPERECORD*)realloc(m_MorphShape.StartEdges.ShapeRecords, m_NumberStartShapes*sizeof(SWF_SHAPERECORD)); memcpy(&m_MorphShape.StartEdges.ShapeRecords[m_NumberStartShapes-1], &curvedEdgeEntry, sizeof(SWF_SHAPERECORD)); } else { m_NumberEndShapes++; if (m_MorphShape.EndEdges.ShapeRecords == NULL) m_MorphShape.EndEdges.ShapeRecords = (SWF_SHAPERECORD*)malloc(sizeof(SWF_SHAPERECORD)); else m_MorphShape.EndEdges.ShapeRecords = (SWF_SHAPERECORD*)realloc(m_MorphShape.EndEdges.ShapeRecords, m_NumberEndShapes*sizeof(SWF_SHAPERECORD)); memcpy(&m_MorphShape.EndEdges.ShapeRecords[m_NumberEndShapes-1], &curvedEdgeEntry, sizeof(SWF_SHAPERECORD)); } } void CSWFMorphShape::AddCurveSegment(float controlPointX, float controlPointY, float anchorPointX, float anchorPointY, bool bStart) { POINT_F controlPoint = {controlPointX, controlPointY}; POINT_F anchorPoint = {anchorPointX, anchorPointY}; AddCurveSegment(controlPoint, anchorPoint, bStart); } UCHAR* CSWFMorphShape::BuildSWFStream() { int newLength; UCHAR numStartFillIndexBits=0, numStartLineIndexBits=0, numEndFillIndexBits=0, numEndLineIndexBits=0; UCHAR *pStartShapeRecordBuffer=NULL, *pEndShapeRecordBuffer=NULL; int recordStartStreamLength=0, recordEndStreamLength=0; // Free shape stream if (m_SWFStream != NULL) { free(m_SWFStream); m_SWFStream = NULL; } // Define EndShapeRecord tag SWF_SHAPERECORD endShapeRecord; memset(&endShapeRecord, 0, sizeof(SWF_SHAPERECORD)); // Add EndShapeRecord to the StartShapeRecordArray m_NumberStartShapes++; if (m_MorphShape.StartEdges.ShapeRecords == NULL) m_MorphShape.StartEdges.ShapeRecords = (SWF_SHAPERECORD*)malloc(sizeof(SWF_SHAPERECORD)); else m_MorphShape.StartEdges.ShapeRecords = (SWF_SHAPERECORD*)realloc(m_MorphShape.StartEdges.ShapeRecords, m_NumberStartShapes*sizeof(SWF_SHAPERECORD)); memcpy(&m_MorphShape.StartEdges.ShapeRecords[m_NumberStartShapes-1], &endShapeRecord, sizeof(SWF_SHAPERECORD)); // Add EndShapeRecord to the EndShapeRecordArray m_NumberEndShapes++; if (m_MorphShape.EndEdges.ShapeRecords == NULL) m_MorphShape.EndEdges.ShapeRecords = (SWF_SHAPERECORD*)malloc(sizeof(SWF_SHAPERECORD)); else m_MorphShape.EndEdges.ShapeRecords = (SWF_SHAPERECORD*)realloc(m_MorphShape.EndEdges.ShapeRecords, m_NumberEndShapes*sizeof(SWF_SHAPERECORD)); memcpy(&m_MorphShape.EndEdges.ShapeRecords[m_NumberEndShapes-1], &endShapeRecord, sizeof(SWF_SHAPERECORD)); // Build shape bounds rectangle .SWF stream CSWFRectangle startRectangle, endRectangle; startRectangle.SetRectangle(m_MorphShape.StartBounds); endRectangle.SetRectangle(m_MorphShape.EndBounds); UCHAR* pStartRectangleBuffer = startRectangle.BuildSWFStream(); UCHAR* pEndRectangleBuffer = endRectangle.BuildSWFStream(); // Calculate total shape tag length m_MorphShape.Header.Length += sizeof(USHORT); // Length of CharacterID m_MorphShape.Header.Length += startRectangle.GetSWFStreamLength(); // Length of StartBounds rectangle m_MorphShape.Header.Length += endRectangle.GetSWFStreamLength(); // Length of EndBounds rectangle m_MorphShape.Header.Length += sizeof(ULONG); // Length of Offset field m_MorphShape.Header.Length += 2*sizeof(UCHAR); // Length of NumLineAndFillBits field // Length of FillStyleArray if (m_MorphShape.MorphFillStyles.FillStyleCountExtended != 0) { // Calculate NumFillIndexBits while (pow(2,numStartFillIndexBits) < (m_MorphShape.MorphFillStyles.FillStyleCountExtended+1)) numStartFillIndexBits++; int fillStyleArraySize = sizeof(UCHAR); if (m_MorphShape.MorphFillStyles.FillStyleCountExtended > 255) fillStyleArraySize += sizeof(USHORT); for (int i=0; i<m_MorphShape.MorphFillStyles.FillStyleCountExtended; i++) { if (m_MorphShape.MorphFillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_SOLID) fillStyleArraySize += (sizeof(UCHAR) + 2*sizeof(SWF_RGBA)); else if ((m_MorphShape.MorphFillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_LINEARGRADIENT) || (m_MorphShape.MorphFillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_RADIALGRADIENT)) { CSWFMatrix startGradientMatrix, endGradientMatrix; startGradientMatrix.SetMatrix(m_MorphShape.MorphFillStyles.FillStyles[i].StartGradientMatrix); endGradientMatrix.SetMatrix(m_MorphShape.MorphFillStyles.FillStyles[i].EndGradientMatrix); startGradientMatrix.BuildSWFStream(); endGradientMatrix.BuildSWFStream(); fillStyleArraySize += 2*sizeof(UCHAR); fillStyleArraySize += startGradientMatrix.GetSWFStreamLength(); fillStyleArraySize += endGradientMatrix.GetSWFStreamLength(); fillStyleArraySize += m_MorphShape.MorphFillStyles.FillStyles[i].Gradient.NumGradients*sizeof(SWF_MORPHGRADIENTRECORD); } else if ((m_MorphShape.MorphFillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_BITMAP_0) || (m_MorphShape.MorphFillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_BITMAP_1) || (m_MorphShape.MorphFillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_BITMAP_2) || (m_MorphShape.MorphFillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_BITMAP_3)) { CSWFMatrix startBitmapMatrix, endBitmapMatrix; startBitmapMatrix.SetMatrix(m_MorphShape.MorphFillStyles.FillStyles[i].StartBitmapMatrix); endBitmapMatrix.SetMatrix(m_MorphShape.MorphFillStyles.FillStyles[i].EndBitmapMatrix); startBitmapMatrix.BuildSWFStream(); endBitmapMatrix.BuildSWFStream(); fillStyleArraySize += (sizeof(UCHAR) + sizeof(USHORT)); fillStyleArraySize += startBitmapMatrix.GetSWFStreamLength(); fillStyleArraySize += endBitmapMatrix.GetSWFStreamLength(); } } m_MorphShape.Header.Length += fillStyleArraySize; m_MorphShape.Offset += fillStyleArraySize; } else { m_MorphShape.Header.Length += sizeof(UCHAR); m_MorphShape.Offset += sizeof(UCHAR); } // Length of LineStyleArray if (m_MorphShape.MorphLineStyles.LineStyleCountExtended != 0) { // Calculate NumLineIndexBits while (pow(2,numStartLineIndexBits) < (m_MorphShape.MorphLineStyles.LineStyleCountExtended+1)) numStartLineIndexBits++; int lineStyleArraySize = sizeof(UCHAR) + m_MorphShape.MorphLineStyles.LineStyleCountExtended*sizeof(SWF_MORPHLINESTYLE); if (m_MorphShape.MorphLineStyles.LineStyleCountExtended > 255) lineStyleArraySize += sizeof(USHORT); m_MorphShape.Header.Length += lineStyleArraySize; m_MorphShape.Offset += lineStyleArraySize; } else { m_MorphShape.Header.Length += sizeof(UCHAR); m_MorphShape.Offset += sizeof(UCHAR); } // Length of StartShapeRecordArray if (m_NumberStartShapes != 0) { // Build StartRecordArray .SWF stream pStartShapeRecordBuffer = BuildRecordArraySWFStream(numStartLineIndexBits, numStartFillIndexBits, recordStartStreamLength, m_MorphShape.StartEdges.ShapeRecords, m_NumberStartShapes); m_MorphShape.Header.Length += recordStartStreamLength; m_MorphShape.Offset += recordStartStreamLength; } else { m_MorphShape.Header.Length += sizeof(UCHAR); m_MorphShape.Offset += sizeof(UCHAR); } // Length of EndShapeRecordArray if (m_NumberEndShapes != 0) { // Build EndRecordArray .SWF stream pEndShapeRecordBuffer = BuildRecordArraySWFStream(numEndLineIndexBits, numEndFillIndexBits, recordEndStreamLength, m_MorphShape.EndEdges.ShapeRecords, m_NumberEndShapes); m_MorphShape.Header.Length += recordEndStreamLength; } else m_MorphShape.Header.Length += sizeof(UCHAR); m_MorphShape.Offset++; // Write RecordHeader tag to .SWF stream newLength = m_SWFStreamLength + sizeof(SWF_RECORDHEADER_LONG); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, &m_MorphShape.Header, sizeof(SWF_RECORDHEADER_LONG)); m_SWFStreamLength = newLength; // Write CharacterID to .SWF stream newLength = m_SWFStreamLength + sizeof(USHORT); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, &m_MorphShape.CharacterID, sizeof(USHORT)); m_SWFStreamLength = newLength; // Write StartBounds to .SWF stream newLength = m_SWFStreamLength + startRectangle.GetSWFStreamLength(); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, pStartRectangleBuffer, startRectangle.GetSWFStreamLength()); m_SWFStreamLength = newLength; // Write EndBounds to .SWF stream newLength = m_SWFStreamLength + endRectangle.GetSWFStreamLength(); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, pEndRectangleBuffer, endRectangle.GetSWFStreamLength()); m_SWFStreamLength = newLength; // Write Offset to .SWF stream newLength = m_SWFStreamLength + sizeof(ULONG); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, &m_MorphShape.Offset, sizeof(ULONG)); m_SWFStreamLength = newLength; // Write FillStyleArray to .SWF stream if (m_MorphShape.MorphFillStyles.FillStyleCountExtended != 0) { if (m_MorphShape.MorphFillStyles.FillStyleCountExtended < 255) m_MorphShape.MorphFillStyles.FillStyleCount = (UCHAR)m_MorphShape.MorphFillStyles.FillStyleCountExtended; // Write FillStyleCount to .SWF stream newLength = m_SWFStreamLength + sizeof(UCHAR); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, &m_MorphShape.MorphFillStyles.FillStyleCount, sizeof(UCHAR)); m_SWFStreamLength = newLength; if (m_MorphShape.MorphFillStyles.FillStyleCountExtended > 255) { // Write FillStyleCountExtended to .SWF stream newLength = m_SWFStreamLength + sizeof(USHORT); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, &m_MorphShape.MorphFillStyles.FillStyleCountExtended, sizeof(USHORT)); m_SWFStreamLength = newLength; } // Write FillStyles to .SWF stream for (int i=0; i<m_MorphShape.MorphFillStyles.FillStyleCountExtended; i++) { // Write FillStyle to .SWF stream if (m_MorphShape.MorphFillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_SOLID) { newLength = m_SWFStreamLength + sizeof(UCHAR) + 2*sizeof(SWF_RGBA); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, &m_MorphShape.MorphFillStyles.FillStyles[i].FillStyleType, sizeof(UCHAR)); memcpy(m_SWFStream+m_SWFStreamLength+sizeof(UCHAR), &m_MorphShape.MorphFillStyles.FillStyles[i].StartColor, sizeof(SWF_RGBA)); memcpy(m_SWFStream+m_SWFStreamLength+sizeof(UCHAR)+sizeof(SWF_RGBA), &m_MorphShape.MorphFillStyles.FillStyles[i].EndColor, sizeof(SWF_RGBA)); m_SWFStreamLength = newLength; } else if ((m_MorphShape.MorphFillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_LINEARGRADIENT) || (m_MorphShape.MorphFillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_RADIALGRADIENT)) { newLength = m_SWFStreamLength + sizeof(UCHAR); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, &m_MorphShape.MorphFillStyles.FillStyles[i].FillStyleType, sizeof(UCHAR)); m_SWFStreamLength = newLength; CSWFMatrix startGradientMatrix, endGradientMatrix; startGradientMatrix.SetMatrix(m_MorphShape.MorphFillStyles.FillStyles[i].StartGradientMatrix); UCHAR* pStartGradientMatrixBuffer = startGradientMatrix.BuildSWFStream(); int nStartGradientMatrixLength = startGradientMatrix.GetSWFStreamLength(); endGradientMatrix.SetMatrix(m_MorphShape.MorphFillStyles.FillStyles[i].EndGradientMatrix); UCHAR* pEndGradientMatrixBuffer = endGradientMatrix.BuildSWFStream(); int nEndGradientMatrixLength = endGradientMatrix.GetSWFStreamLength(); newLength = m_SWFStreamLength + nStartGradientMatrixLength + nEndGradientMatrixLength; if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, pStartGradientMatrixBuffer, nStartGradientMatrixLength); memcpy(m_SWFStream+m_SWFStreamLength+nStartGradientMatrixLength, pEndGradientMatrixBuffer, nEndGradientMatrixLength); m_SWFStreamLength = newLength; newLength = m_SWFStreamLength + sizeof(UCHAR); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, &m_MorphShape.MorphFillStyles.FillStyles[i].Gradient.NumGradients, sizeof(UCHAR)); m_SWFStreamLength = newLength; for (int j=0; j<m_MorphShape.MorphFillStyles.FillStyles[i].Gradient.NumGradients; j++) { newLength = m_SWFStreamLength + 2*(sizeof(UCHAR) + sizeof(SWF_RGBA)); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, &m_MorphShape.MorphFillStyles.FillStyles[i].Gradient.GradientRecords[j].StartRatio, sizeof(UCHAR)); memcpy(m_SWFStream+m_SWFStreamLength+sizeof(UCHAR), &m_MorphShape.MorphFillStyles.FillStyles[i].Gradient.GradientRecords[j].StartColor, sizeof(SWF_RGBA)); memcpy(m_SWFStream+m_SWFStreamLength+sizeof(UCHAR)+sizeof(SWF_RGBA), &m_MorphShape.MorphFillStyles.FillStyles[i].Gradient.GradientRecords[j].EndRatio, sizeof(UCHAR)); memcpy(m_SWFStream+m_SWFStreamLength+sizeof(UCHAR)+sizeof(SWF_RGBA)+sizeof(UCHAR), &m_MorphShape.MorphFillStyles.FillStyles[i].Gradient.GradientRecords[j].EndColor, sizeof(SWF_RGBA)); m_SWFStreamLength = newLength; } } else if ((m_MorphShape.MorphFillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_BITMAP_0) || (m_MorphShape.MorphFillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_BITMAP_1) || (m_MorphShape.MorphFillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_BITMAP_2) || (m_MorphShape.MorphFillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_BITMAP_3)) { newLength = m_SWFStreamLength + sizeof(UCHAR); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, &m_MorphShape.MorphFillStyles.FillStyles[i].FillStyleType, sizeof(UCHAR)); m_SWFStreamLength = newLength; newLength = m_SWFStreamLength + sizeof(USHORT); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, &m_MorphShape.MorphFillStyles.FillStyles[i].BitmapID, sizeof(USHORT)); m_SWFStreamLength = newLength; CSWFMatrix startBitmapMatrix, endBitmapMatrix; startBitmapMatrix.SetMatrix(m_MorphShape.MorphFillStyles.FillStyles[i].StartBitmapMatrix); UCHAR* pStartBitmapMatrixBuffer = startBitmapMatrix.BuildSWFStream(); int nStartBitmapMatrixLength = startBitmapMatrix.GetSWFStreamLength(); endBitmapMatrix.SetMatrix(m_MorphShape.MorphFillStyles.FillStyles[i].EndBitmapMatrix); UCHAR* pEndBitmapMatrixBuffer = endBitmapMatrix.BuildSWFStream(); int nEndBitmapMatrixLength = endBitmapMatrix.GetSWFStreamLength(); newLength = m_SWFStreamLength + nStartBitmapMatrixLength + nEndBitmapMatrixLength; if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, pStartBitmapMatrixBuffer, nStartBitmapMatrixLength); memcpy(m_SWFStream+m_SWFStreamLength+nStartBitmapMatrixLength, pEndBitmapMatrixBuffer, nEndBitmapMatrixLength); m_SWFStreamLength = newLength; } } } else { // Write empty FillStyleArray to .SWF stream m_MorphShape.MorphFillStyles.FillStyleCount = 0; newLength = m_SWFStreamLength + sizeof(UCHAR); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, &m_MorphShape.MorphFillStyles.FillStyleCount, sizeof(UCHAR)); m_SWFStreamLength = newLength; } // Write LineStyleArray to .SWF stream if (m_MorphShape.MorphLineStyles.LineStyleCountExtended != 0) { if (m_MorphShape.MorphLineStyles.LineStyleCountExtended < 255) m_MorphShape.MorphLineStyles.LineStyleCount = (UCHAR)m_MorphShape.MorphLineStyles.LineStyleCountExtended; // Write LineStyleCount to .SWF stream newLength = m_SWFStreamLength + sizeof(UCHAR); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, &m_MorphShape.MorphLineStyles.LineStyleCount, sizeof(UCHAR)); m_SWFStreamLength = newLength; if (m_MorphShape.MorphLineStyles.LineStyleCountExtended > 255) { // Write LineStyleCountExtended to .SWF stream newLength = m_SWFStreamLength + sizeof(USHORT); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, &m_MorphShape.MorphLineStyles.LineStyleCountExtended, sizeof(USHORT)); m_SWFStreamLength = newLength; } // Write LineStyles to .SWF stream for (int i=0; i<m_MorphShape.MorphLineStyles.LineStyleCountExtended; i++) { // Write LineStyle to .SWF stream newLength = m_SWFStreamLength + sizeof(SWF_MORPHLINESTYLE); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, &m_MorphShape.MorphLineStyles.LineStyles[i], sizeof(SWF_MORPHLINESTYLE)); m_SWFStreamLength = newLength; } } else { // Write empty LineStyleArray to .SWF stream m_MorphShape.MorphLineStyles.LineStyleCount = 0; newLength = m_SWFStreamLength + sizeof(UCHAR); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, &m_MorphShape.MorphLineStyles.LineStyleCount, sizeof(UCHAR)); m_SWFStreamLength = newLength; } // Write NumStartFillAndLineBits to .SWF stream UCHAR numStartLineAndFillIndexBits = (numStartFillIndexBits<<4) | numStartLineIndexBits; newLength = m_SWFStreamLength + sizeof(UCHAR); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, &numStartLineAndFillIndexBits, sizeof(UCHAR)); m_SWFStreamLength = newLength; // Write StartShapeRecordArray to .SWF stream if (pStartShapeRecordBuffer != NULL) { newLength = m_SWFStreamLength + recordStartStreamLength; if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, pStartShapeRecordBuffer, recordStartStreamLength); m_SWFStreamLength = newLength; // Free memory free(pStartShapeRecordBuffer); } // Write NumEndFillAndLineBits to .SWF stream UCHAR numEndLineAndFillIndexBits = (numEndFillIndexBits<<4) | numEndLineIndexBits; newLength = m_SWFStreamLength + sizeof(UCHAR); if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, &numEndLineAndFillIndexBits, sizeof(UCHAR)); m_SWFStreamLength = newLength; // Write EndShapeRecordArray to .SWF stream if (pEndShapeRecordBuffer != NULL) { newLength = m_SWFStreamLength + recordEndStreamLength; if (m_SWFStreamLength == 0) m_SWFStream = (BYTE*)malloc(newLength); else m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); memcpy(m_SWFStream+m_SWFStreamLength, pEndShapeRecordBuffer, recordEndStreamLength); m_SWFStreamLength = newLength; // Free memory free(pEndShapeRecordBuffer); } return m_SWFStream; } int CSWFMorphShape::GetSWFStreamLength() { return m_SWFStreamLength; } UCHAR* CSWFMorphShape::BuildRecordArraySWFStream(int numLineIndexBits, int numFillIndexBits, int& recordStreamLength, SWF_SHAPERECORD* pRecordArray, int numShapes) { UCHAR* pShapeRecordBuffer = NULL; int numBits=0, bitOffset=0, allocBytes=0; recordStreamLength = 0; // Write ShapeRecords to .SWF stream for (int i=0; i<numShapes; i++) { BOOL bEdgeTypeRecord = pRecordArray[i].SWF_ENDSHAPERECORD.ShapeFlags & 0x20; BOOL bStraightEdge = pRecordArray[i].SWF_ENDSHAPERECORD.ShapeFlags & 0x10; BOOL bStyleChangeRecord = pRecordArray[i].SWF_ENDSHAPERECORD.ShapeFlags & 0x0F; // Edge type record (StraightEdgeRecord or CurvedEdgeRecord); if (bEdgeTypeRecord) { // StraightEdgeRecord type if (bStraightEdge) { // ShapeFlags bit-field numBits += (7 + 2*pRecordArray[i].SWF_STRAIGHTEDGERECORD.NumBits); // Allocate memory if (numBits > (allocBytes*8)) { int oldAllocBytes = allocBytes; allocBytes = numBits / 8; if ((numBits % 8) != 0) allocBytes++; if (pShapeRecordBuffer == NULL) { pShapeRecordBuffer = (UCHAR*)malloc(allocBytes*sizeof(UCHAR)); memset(pShapeRecordBuffer, 0, allocBytes); } else { UCHAR* pTempBuffer = (UCHAR*)malloc(oldAllocBytes*sizeof(UCHAR)); memcpy(pTempBuffer, pShapeRecordBuffer, oldAllocBytes); pShapeRecordBuffer = (UCHAR*)realloc(pShapeRecordBuffer, allocBytes*sizeof(UCHAR)); memset(pShapeRecordBuffer, 0, allocBytes); memcpy(pShapeRecordBuffer, pTempBuffer, oldAllocBytes); free(pTempBuffer); } } // Write ShapeFlags bit-field int currentByte = bitOffset / 8; BYTE shapeFlags = pRecordArray[i].SWF_STRAIGHTEDGERECORD.ShapeFlags << 1; BYTE mask = 0x80; for (int j=0; j<7; j++) { pShapeRecordBuffer[currentByte] |= (((shapeFlags & mask) >> (7-j)) << ((currentByte+1)*8-bitOffset-1)); bitOffset++; if ((bitOffset != 0) && (bitOffset % 8) == 0) currentByte++; mask = mask >> 1; } // Write DeltaX bit-field ULONG deltaX = pRecordArray[i].SWF_STRAIGHTEDGERECORD.DeltaX << (32-pRecordArray[i].SWF_STRAIGHTEDGERECORD.NumBits); ULONG maskDeltaX = 0x80000000; for (j=0; j<pRecordArray[i].SWF_STRAIGHTEDGERECORD.NumBits; j++) { pShapeRecordBuffer[currentByte] |= LOBYTE(((deltaX & maskDeltaX) >> (31-j)) << ((currentByte+1)*8-bitOffset-1)); bitOffset++; if ((bitOffset != 0) && (bitOffset % 8) == 0) currentByte++; maskDeltaX = maskDeltaX >> 1; } // Write DeltaY bit-field ULONG deltaY = pRecordArray[i].SWF_STRAIGHTEDGERECORD.DeltaY << (32-pRecordArray[i].SWF_STRAIGHTEDGERECORD.NumBits); ULONG maskDeltaY = 0x80000000; for (j=0; j<pRecordArray[i].SWF_STRAIGHTEDGERECORD.NumBits; j++) { pShapeRecordBuffer[currentByte] |= LOBYTE(((deltaY & maskDeltaY) >> (31-j)) << ((currentByte+1)*8-bitOffset-1)); bitOffset++; if ((bitOffset != 0) && (bitOffset % 8) == 0) currentByte++; maskDeltaY = maskDeltaY >> 1; } } // CurvedEdgeRecord type else { // ShapeFlags bit-field numBits += (6 + 4*pRecordArray[i].SWF_CURVEDEDGERECORD.NumBits); // Allocate memory if (numBits > (allocBytes*8)) { int oldAllocBytes = allocBytes; allocBytes = numBits / 8; if ((numBits % 8) != 0) allocBytes++; if (pShapeRecordBuffer == NULL) { pShapeRecordBuffer = (UCHAR*)malloc(allocBytes*sizeof(UCHAR)); memset(pShapeRecordBuffer, 0, allocBytes); } else { UCHAR* pTempBuffer = (UCHAR*)malloc(oldAllocBytes*sizeof(UCHAR)); memcpy(pTempBuffer, pShapeRecordBuffer, oldAllocBytes); pShapeRecordBuffer = (UCHAR*)realloc(pShapeRecordBuffer, allocBytes*sizeof(UCHAR)); memset(pShapeRecordBuffer, 0, allocBytes); memcpy(pShapeRecordBuffer, pTempBuffer, oldAllocBytes); free(pTempBuffer); } } // Write ShapeFlags bit-field int currentByte = bitOffset / 8; BYTE shapeFlags = pRecordArray[i].SWF_CURVEDEDGERECORD.ShapeFlags << 2; BYTE mask = 0x80; for (int j=0; j<6; j++) { pShapeRecordBuffer[currentByte] |= (((shapeFlags & mask) >> (7-j)) << ((currentByte+1)*8-bitOffset-1)); bitOffset++; if ((bitOffset != 0) && (bitOffset % 8) == 0) currentByte++; mask = mask >> 1; } // Write ControlDeltaX bit-field ULONG controlDeltaX = pRecordArray[i].SWF_CURVEDEDGERECORD.ControlDeltaX << (32-pRecordArray[i].SWF_CURVEDEDGERECORD.NumBits); ULONG maskControlDeltaX = 0x80000000; for (j=0; j<pRecordArray[i].SWF_CURVEDEDGERECORD.NumBits; j++) { pShapeRecordBuffer[currentByte] |= LOBYTE(((controlDeltaX & maskControlDeltaX) >> (31-j)) << ((currentByte+1)*8-bitOffset-1)); bitOffset++; if ((bitOffset != 0) && (bitOffset % 8) == 0) currentByte++; maskControlDeltaX = maskControlDeltaX >> 1; } // Write ControlDeltaY bit-field ULONG controlDeltaY = pRecordArray[i].SWF_CURVEDEDGERECORD.ControlDeltaY << (32-pRecordArray[i].SWF_CURVEDEDGERECORD.NumBits); ULONG maskControlDeltaY = 0x80000000; for (j=0; j<pRecordArray[i].SWF_CURVEDEDGERECORD.NumBits; j++) { pShapeRecordBuffer[currentByte] |= LOBYTE(((controlDeltaY & maskControlDeltaY) >> (31-j)) << ((currentByte+1)*8-bitOffset-1)); bitOffset++; if ((bitOffset != 0) && (bitOffset % 8) == 0) currentByte++; maskControlDeltaY = maskControlDeltaY >> 1; } // Write AnchorDeltaX bit-field ULONG anchorDeltaX = pRecordArray[i].SWF_CURVEDEDGERECORD.AnchorDeltaX << (32-pRecordArray[i].SWF_CURVEDEDGERECORD.NumBits); ULONG maskAnchorDeltaX = 0x80000000; for (j=0; j<pRecordArray[i].SWF_CURVEDEDGERECORD.NumBits; j++) { pShapeRecordBuffer[currentByte] |= LOBYTE(((anchorDeltaX & maskAnchorDeltaX) >> (31-j)) << ((currentByte+1)*8-bitOffset-1)); bitOffset++; if ((bitOffset != 0) && (bitOffset % 8) == 0) currentByte++; maskAnchorDeltaX = maskAnchorDeltaX >> 1; } // Write AnchorDeltaY bit-field ULONG anchorDeltaY = pRecordArray[i].SWF_CURVEDEDGERECORD.AnchorDeltaY << (32-pRecordArray[i].SWF_CURVEDEDGERECORD.NumBits); ULONG maskAnchorDeltaY = 0x80000000; for (j=0; j<pRecordArray[i].SWF_CURVEDEDGERECORD.NumBits; j++) { pShapeRecordBuffer[currentByte] |= LOBYTE(((anchorDeltaY & maskAnchorDeltaY) >> (31-j)) << ((currentByte+1)*8-bitOffset-1)); bitOffset++; if ((bitOffset != 0) && (bitOffset % 8) == 0) currentByte++; maskAnchorDeltaY = maskAnchorDeltaY >> 1; } } } // Non-edge type record (EndShapeRecord or StyleChangeRecord) else { // StyleChangeRecord type if (bStyleChangeRecord) { // ShapeFlags bit-field numBits += 6; // StateMoveTo bit-field if (pRecordArray[i].SWF_STYLECHANGERECORD.ShapeFlags & 0x01) numBits += (5 + 2*pRecordArray[i].SWF_STYLECHANGERECORD.MoveBits); // StateFillStyle0 bit-field if (pRecordArray[i].SWF_STYLECHANGERECORD.ShapeFlags & 0x02) numBits += numFillIndexBits; // StateFillStyle1 bit-field if (pRecordArray[i].SWF_STYLECHANGERECORD.ShapeFlags & 0x04) numBits += numFillIndexBits; // StateLineStyle bit-field if (pRecordArray[i].SWF_STYLECHANGERECORD.ShapeFlags & 0x08) numBits += numLineIndexBits; // Allocate memory if (numBits > (allocBytes*8)) { int oldAllocBytes = allocBytes; allocBytes = numBits / 8; if ((numBits % 8) != 0) allocBytes++; if (pShapeRecordBuffer == NULL) { pShapeRecordBuffer = (UCHAR*)malloc(allocBytes*sizeof(UCHAR)); memset(pShapeRecordBuffer, 0, allocBytes); } else { UCHAR* pTempBuffer = (UCHAR*)malloc(oldAllocBytes*sizeof(UCHAR)); memcpy(pTempBuffer, pShapeRecordBuffer, oldAllocBytes); pShapeRecordBuffer = (UCHAR*)realloc(pShapeRecordBuffer, allocBytes*sizeof(UCHAR)); memset(pShapeRecordBuffer, 0, allocBytes); memcpy(pShapeRecordBuffer, pTempBuffer, oldAllocBytes); free(pTempBuffer); } } // Write ShapeFlags bit-field int currentByte = bitOffset / 8; BYTE shapeFlags = pRecordArray[i].SWF_STYLECHANGERECORD.ShapeFlags << 2; BYTE mask = 0x80; for (int j=0; j<6; j++) { pShapeRecordBuffer[currentByte] |= (((shapeFlags & mask) >> (7-j)) << ((currentByte+1)*8-bitOffset-1)); bitOffset++; if ((bitOffset != 0) && (bitOffset % 8) == 0) currentByte++; mask = mask >> 1; } // Write StateMoveTo bit-field if (pRecordArray[i].SWF_STYLECHANGERECORD.ShapeFlags & 0x01) { int j; BYTE shapeMoveBits = pRecordArray[i].SWF_STYLECHANGERECORD.MoveBits << 3; BYTE mask = 0x80; for (j=0; j<5; j++) { pShapeRecordBuffer[currentByte] |= LOBYTE(((shapeMoveBits & mask) >> (7-j)) << ((currentByte+1)*8-bitOffset-1)); bitOffset++; if ((bitOffset != 0) && (bitOffset % 8) == 0) currentByte++; mask = mask >> 1; } // Write MoveDeltaX bit-field ULONG moveDeltaX = pRecordArray[i].SWF_STYLECHANGERECORD.MoveDeltaX << (32-pRecordArray[i].SWF_STYLECHANGERECORD.MoveBits); ULONG maskMoveX = 0x80000000; for (j=0; j<pRecordArray[i].SWF_STYLECHANGERECORD.MoveBits; j++) { pShapeRecordBuffer[currentByte] |= LOBYTE(((moveDeltaX & maskMoveX) >> (31-j)) << ((currentByte+1)*8-bitOffset-1)); bitOffset++; if ((bitOffset != 0) && (bitOffset % 8) == 0) currentByte++; maskMoveX = maskMoveX >> 1; } // Write MoveDeltaY bit-field ULONG moveDeltaY = pRecordArray[i].SWF_STYLECHANGERECORD.MoveDeltaY << (32-pRecordArray[i].SWF_STYLECHANGERECORD.MoveBits); ULONG maskMoveY = 0x80000000; for (j=0; j<pRecordArray[i].SWF_STYLECHANGERECORD.MoveBits; j++) { pShapeRecordBuffer[currentByte] |= LOBYTE(((moveDeltaY & maskMoveY) >> (31-j)) << ((currentByte+1)*8-bitOffset-1)); bitOffset++; if ((bitOffset != 0) && (bitOffset % 8) == 0) currentByte++; maskMoveY = maskMoveY >> 1; } } // Write StateFillStyle0 bit-field if (pRecordArray[i].SWF_STYLECHANGERECORD.ShapeFlags & 0x02) { WORD shapeFillStyleBits = pRecordArray[i].SWF_STYLECHANGERECORD.FillStyle0 << (16-numFillIndexBits); WORD mask = 0x8000; for (int j=0; j<numFillIndexBits; j++) { pShapeRecordBuffer[currentByte] |= LOBYTE(((shapeFillStyleBits & mask) >> (15-j)) << ((currentByte+1)*8-bitOffset-1)); bitOffset++; if ((bitOffset != 0) && (bitOffset % 8) == 0) currentByte++; mask = mask >> 1; } } // Write StateFillStyle1 bit-field if (pRecordArray[i].SWF_STYLECHANGERECORD.ShapeFlags & 0x04) { WORD shapeFillStyleBits = pRecordArray[i].SWF_STYLECHANGERECORD.FillStyle1 << (16-numFillIndexBits); WORD mask = 0x8000; for (int j=0; j<numFillIndexBits; j++) { pShapeRecordBuffer[currentByte] |= LOBYTE(((shapeFillStyleBits & mask) >> (15-j)) << ((currentByte+1)*8-bitOffset-1)); bitOffset++; if ((bitOffset != 0) && (bitOffset % 8) == 0) currentByte++; mask = mask >> 1; } } // Write StateLineStyle bit-field if (pRecordArray[i].SWF_STYLECHANGERECORD.ShapeFlags & 0x08) { WORD shapeLineStyleBits = pRecordArray[i].SWF_STYLECHANGERECORD.LineStyle << (16-numLineIndexBits); WORD mask = 0x8000; for (int j=0; j<numLineIndexBits; j++) { pShapeRecordBuffer[currentByte] |= LOBYTE(((shapeLineStyleBits & mask) >> (15-j)) << ((currentByte+1)*8-bitOffset-1)); bitOffset++; if ((bitOffset != 0) && (bitOffset % 8) == 0) currentByte++; mask = mask >> 1; } } } // EndShapeRecord type else { // ShapeFlags bit-field numBits += 6; // Allocate memory if ((allocBytes*8 - bitOffset) < 6) { int oldAllocBytes = allocBytes; allocBytes++; if (pShapeRecordBuffer == NULL) { pShapeRecordBuffer = (UCHAR*)malloc(allocBytes*sizeof(UCHAR)); memset(pShapeRecordBuffer, 0, allocBytes); } else { UCHAR* pTempBuffer = (UCHAR*)malloc(oldAllocBytes*sizeof(UCHAR)); memcpy(pTempBuffer, pShapeRecordBuffer, oldAllocBytes); pShapeRecordBuffer = (UCHAR*)realloc(pShapeRecordBuffer, allocBytes*sizeof(UCHAR)); memset(pShapeRecordBuffer, 0, allocBytes); memcpy(pShapeRecordBuffer, pTempBuffer, oldAllocBytes); free(pTempBuffer); } } } } } // Set new RecordShapeArray length recordStreamLength = allocBytes; return pShapeRecordBuffer; } void CSWFMorphShape::Scale(float scaleX, float scaleY) { MATRIX_F matrix; m_TransformationMatrix.GetMatrix(matrix); matrix.scaleX = scaleX; matrix.scaleY = scaleY; m_TransformationMatrix.SetMatrix(matrix); } void CSWFMorphShape::Rotate(float angle) { MATRIX_F matrix; m_TransformationMatrix.GetMatrix(matrix); if (((int)angle % 90) == 0) angle += 0.05f; double a = PI / 180; matrix.scaleX = (float)cos(angle*a); matrix.scaleY = (float)cos(angle*a); matrix.rotateSkew0 = (float)sin(angle*a); matrix.rotateSkew1 = -(float)sin(angle*a); m_TransformationMatrix.SetMatrix(matrix); } void CSWFMorphShape::Translate(float translateX, float translateY) { MATRIX_F matrix; m_TransformationMatrix.GetMatrix(matrix); matrix.translateX = translateX; matrix.translateY = translateY; m_TransformationMatrix.SetMatrix(matrix); } void CSWFMorphShape::Shear(float shearX, float shearY) { MATRIX_F matrix; m_TransformationMatrix.GetMatrix(matrix); matrix.rotateSkew0 = shearX; matrix.rotateSkew1 = shearY; m_TransformationMatrix.SetMatrix(matrix); }